package com.orangelife.service.offset.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import net.sf.json.JSONObject;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.orangelife.common.MybaitsGenericDaoSubLogic;
import com.orangelife.exception.AppBizException;
import com.orangelife.service.feeDetail.IFeeDetailService;
import com.orangelife.service.offset.IOffsetService;
import com.orangelife.service.propFeeAccount.IPropFeeAccountService;
import com.orangelife.service.propFeeAccount.model.AmountHandleDto;
import com.orangelife.service.propFeeAccount.model.PropFeeAccountDto;
import com.orangelife.service.propFeeAmountLog.model.PropFeeAmountLogDto;
import com.orangelife.service.propFeeComm.IPropFeeCommService;
import com.orangelife.service.propFeeComm.model.PayBillInfo;
import com.orangelife.service.propFeeOffsetInfo.IPropFeeOffsetInfoService;
import com.orangelife.service.propFeeOffsetInfo.model.PropFeeOffsetInfoDto;
import com.orangelife.utils.HttpSvcUtils;
import com.orangelife.utils.IdUtil;
import com.orangelife.utils.StringUtils;
import com.orangelife.utils.UrlPath;
import com.orangelife.webservice.service.propFeeOffsetInfo.entity.OffSetDto;

@Service("offsetService")
public class OffsetServiceImpl extends MybaitsGenericDaoSubLogic implements
		IOffsetService {
	@Resource(name = "propFeeAccountService")
	private IPropFeeAccountService propFeeAccountService;
	@Resource(name = "feeDetailService")
	private IFeeDetailService feeDetailService;

	@Resource(name = "propFeeOffsetInfoService")
	private IPropFeeOffsetInfoService propFeeOffsetInfoService;
	@Resource(name = "propFeeCommService")
	private IPropFeeCommService propFeeCommService;

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public synchronized void autoOffset(String commID, String apartmentID,
			String userID, String userName) throws AppBizException {
		if (StringUtils.isBlank(commID)) {
			return;
		}

		if (StringUtils.isBlank(apartmentID)) {

			return;
		}

		// 获取房屋账户余额
		PropFeeAccountDto propFeeAccount = propFeeAccountService
				.findAccountByApartID(apartmentID);
		if (propFeeAccount == null) {

			return;
		}

		if (propFeeAccount.getMoney().compareTo(BigDecimal.ZERO) <= 0) {

			return;
		}

		BigDecimal money = propFeeAccount.getMoney();
		// 获取该用户的缴费细项信息

		List<Map<String, Object>> details = feeDetailService
				.getFeeDetailsForOffset(apartmentID, commID);
		if (details == null || details.size() == 0) {

			return;

		}
		// 遍历进行代扣操作
		BigDecimal amount = null;
		List<String> feeDetailIDs = new ArrayList<String>();

		String minDate = null;
		String mon = null;

		for (Map<String, Object> map : details) {

			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			amount = new BigDecimal(map.get("amount").toString());
			mon = map.get("fee_date").toString();

			if (minDate != null) {

				if (!mon.equals(minDate)) {

					break;
				}

			}
			if (money.compareTo(amount) >= 0) {
				String offsetID = IdUtil.getuuId();
				// 扣钱
				AmountHandleDto a = new AmountHandleDto();
				a.setAccountID(propFeeAccount.getAccountID());
				a.setMoney(amount);
				a.setRemark(map.get("fee_type_name").toString());
				a.setItem(map.get("fee_type_name").toString());
				a.setApartmentID(propFeeAccount.getApartmentID());
				a.setLinkID(offsetID);
				a.setTotalMoney(money);

				Map<String, Object> m = new HashMap<String, Object>();
				m.put("feeDate", mon);
				m.put("feeDetailID", map.get("fee_detail_id").toString());
				a.setLogContent(JSONObject.fromObject(m).toString());
				a.setOperation("2");
				a.setLogType(PropFeeAmountLogDto.OFFSET);
				a.setStatementType("7");
				propFeeAccountService.handleAccount(a);
				// 生成冲抵明细
				PropFeeOffsetInfoDto pof = new PropFeeOffsetInfoDto();
				pof.setAmount(amount);
				pof.setOffsetMoney(amount);
				pof.setFeeDate(map.get("fee_date").toString());
				pof.setFeeDetailID(map.get("fee_detail_id").toString());
				pof.setFeeTypeID(map.get("fee_type_id").toString());
				pof.setCommID(commID);
				pof.setApartmentID(apartmentID);
				pof.setOffsetTime(new Date());
				pof.setOffsetType("1");
				pof.setAccountID(propFeeAccount.getAccountID());
				propFeeOffsetInfoService.addPropFeeOffsetInfo(pof);
				pof.setFeeTypeName(map.get("fee_type_name").toString());
				pof.setFeeDate(mon);
				// 设置细项为已支付
				feeDetailIDs.add(map.get("fee_detail_id").toString());

				money = money.subtract(amount);

				try {
					// // 同步数据到财务中心
					// sendInfoToFinal(pof, commID, apartmentID, map
					// .get("fnumber").toString(), userID, userName);
				} catch (Exception e) {
					// TODO: handle exception
				}
			} else {
				minDate = mon;

			}

		}
		if (feeDetailIDs != null && feeDetailIDs.size() > 0) {
			feeDetailService.setFeeDetailsPay(apartmentID, feeDetailIDs,
					new Date());
		}

		// TODO Auto-generated method stub

	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public synchronized int cancelOffSet(OffSetDto offSetDto)
			throws AppBizException {
		List<String> feeDetailIDs = new ArrayList<String>();

		for (String offsetID : offSetDto.getOffsetIDs()) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}

			PropFeeOffsetInfoDto p = propFeeOffsetInfoService
					.findMorePropFeeOffsetInfoByID(offsetID);

			if (p == null) {
				continue;

			}
			if ("2".equals(p.getStatus())
					|| !("1".equals(p.getOffsetType()) || "3".equals(p
							.getOffsetType()))) {
				continue;
			}

			// 撤销账单
			p.setStatus("2");
			p.setCancelTime(new Date());
			p.setCancelMan(offSetDto.getCancelMan());
			p.setCancelManID(offSetDto.getCancelManID());
			p.setTsedit(new Date());
			int n = propFeeOffsetInfoService.editPropFeeOffsetInfo(p);

			if (n > 0) {
				feeDetailIDs.add(p.getFeeDetailID());
			}

			AmountHandleDto a = new AmountHandleDto();
			a.setAccountID(p.getAccountID());
			a.setMoney(p.getOffsetMoney());
			a.setRemark("撤销" + p.getFeeDate() + "的" + p.getFeeTypeName()
					+ "冲抵费用");
			a.setItem(p.getFeeTypeName());
			a.setApartmentID(p.getApartmentID());
			a.setLinkID(offsetID);

			// a.setTotalMoney(propFeeAccount.getMoney());

			Map<String, Object> m = new HashMap<String, Object>();
			m.put("feeDate", p.getFeeDate());
			m.put("feeDetailID", p.getFeeDetailID());
			a.setLogContent(JSONObject.fromObject(m).toString());
			a.setOperation("1");
			a.setLogType(PropFeeAmountLogDto.CANCEL_OFFSET);
			a.setStatementType("12");
			propFeeAccountService.handleAccount(a);
			feeDetailIDs.add(p.getFeeDetailID());
			// 转账

			//
			// AmountHandleDto amountHandle=new AmountHandleDto();
			// amountHandle.setOperation("1");
			// amountHandle.setAccountID(propFeePaybillItemDto.getLinkID());
			// amountHandle.setMoney(propFeePaybillItemDto.getMoney());
			// amountHandle.setLogType(7);
			// amountHandle.setLinkID(propFeePaybillItemDto.getPaybillID());
			// amountHandle.setCreateuser(userbean.getUserName());
			// amountHandle.setCreateuserID(userbean.getUserID());
			// // amountHandle.setApartmentID(paybill.getApartmentID());
			// amountHandle.setRemark("删除账单归还余额支付的 "+propFeePaybillItemDto.getMoney()+"元");
			// amountHandle.setTotalMoney(propFeeAccount.getMoney());
			// propFeeAccountService.handleAccount(amountHandle);
			// propFeeAccount.setMoney(propFeeAccount.getMoney().add(propFeePaybillItemDto.getMoney()));
		}

		if (feeDetailIDs != null && feeDetailIDs.size() > 0) {
			feeDetailService.setFeeDetailsNoPay(null, feeDetailIDs, new Date());
		}
		// TODO Auto-generated method stub
		return 1;
	}

	// private PropFeeAccountDto getAmountByfeeType(String
	// feeTypeID,Map<String,PropFeeAccountDto> account){
	//
	//
	//
	//
	// }
	// @Override
	// @Transactional(rollbackFor = { AppBizException.class, Exception.class,
	// RuntimeException.class })
	// public void autoOffset(String commID, String apartmentID, String userID,
	// String userName) throws AppBizException {
	// if (StringUtils.isBlank(commID)) {
	// return;
	// }
	//
	// if (StringUtils.isBlank(apartmentID)) {
	//
	// return;
	// }
	//
	// // 获取该用户底下所有房屋账户余额
	// PropFeeAccountDto propFeeAccount = propFeeAccountService
	// .findAccountByApartID(apartmentID);
	//
	// //Map<String,PropFeeAccountDto> account
	// =propFeeAccountService.getAccountMapByApartID(commID, apartmentID, null);
	//
	//
	//
	//
	//
	// if (propFeeAccount == null) {
	//
	// return;
	// }
	//
	// if (propFeeAccount.getMoney().compareTo(BigDecimal.ZERO) <= 0) {
	//
	// return;
	// }
	//
	// BigDecimal money = propFeeAccount.getMoney();
	// // 获取该用户的缴费细项信息
	//
	// List<Map<String, Object>> details = feeDetailService
	// .getFeeDetailsForOffset(apartmentID, commID);
	// if (details == null || details.size() == 0) {
	//
	// return;
	//
	// }
	// // 遍历进行代扣操作
	// BigDecimal amount = null;
	// List<String> feeDetailIDs = new ArrayList<String>();
	//
	// String minDate = null;
	// String mon = null;
	//
	// for (Map<String, Object> map : details) {
	//
	// try {
	// Thread.sleep(10);
	// } catch (InterruptedException e) {
	// // TODO Auto-generated catch block
	// e.printStackTrace();
	// }
	//
	// amount = new BigDecimal(map.get("amount").toString());
	// mon = map.get("fee_date").toString();
	//
	// if (minDate != null) {
	//
	// if (!mon.equals(minDate)) {
	//
	// break;
	// }
	//
	// }
	// if (money.compareTo(amount) >= 0) {
	// String offsetID = IdUtil.getuuId();
	// // 扣钱
	// AmountHandleDto a = new AmountHandleDto();
	// a.setAccountID(propFeeAccount.getAccountID());
	// a.setMoney(amount);
	// a.setRemark(map.get("fee_type_name").toString());
	// a.setItem(map.get("fee_type_name").toString());
	// a.setApartmentID(propFeeAccount.getApartmentID());
	// a.setLinkID(offsetID);
	// a.setTotalMoney(money);
	//
	// Map<String, Object> m = new HashMap<String, Object>();
	// m.put("feeDate", mon);
	// m.put("feeDetailID", map.get("fee_detail_id").toString());
	// a.setLogContent(JSONObject.fromObject(m).toString());
	// a.setOperation("2");
	// a.setLogType(8);
	// a.setStatementType("7");
	// propFeeAccountService.handleAccount(a);
	// // 生成冲抵明细
	// PropFeeOffsetInfoDto pof = new PropFeeOffsetInfoDto();
	// pof.setAmount(amount);
	// pof.setOffsetMoney(amount);
	// pof.setFeeDate(map.get("fee_date").toString());
	// pof.setFeeDetailID(map.get("fee_detail_id").toString());
	// pof.setFeeTypeID(map.get("fee_type_id").toString());
	// pof.setCommID(commID);
	// pof.setApartmentID(apartmentID);
	// pof.setOffsetTime(new Date());
	// pof.setOffsetType("1");
	// propFeeOffsetInfoService.addPropFeeOffsetInfo(pof);
	// pof.setFeeTypeName(map.get("fee_type_name").toString());
	// pof.setFeeDate(mon);
	// // 设置细项为已支付
	// feeDetailIDs.add(map.get("fee_detail_id").toString());
	//
	// money = money.subtract(amount);
	//
	// try {
	// // 同步数据到财务中心
	// sendInfoToFinal(pof, commID, apartmentID, map
	// .get("fnumber").toString(), userID, userName);
	// } catch (Exception e) {
	// // TODO: handle exception
	// }
	// } else {
	// minDate = mon;
	//
	// }
	//
	// }
	// if (feeDetailIDs != null && feeDetailIDs.size() > 0) {
	// feeDetailService.setFeeDetailsPay(apartmentID, feeDetailIDs,
	// new Date());
	// }
	//
	// // TODO Auto-generated method stub
	//
	// }

	public int sendInfoToFinal(PropFeeOffsetInfoDto pof, String commID,
			String apartmentID, String typeCode, String userID, String userName)
			throws AppBizException {

		try {

			if (StringUtils.isBlank(typeCode)) {
				logger.info(pof.getFeeTypeName() + "类目未配置编码无法发送到财务系统");
				return 0;
			}
			PayBillInfo payBillInfo = new PayBillInfo();
			payBillInfo.setApartmentID(apartmentID);
			payBillInfo.setMoney(pof.getOffsetMoney().toString());
			payBillInfo.setCommID(commID);
			payBillInfo.setTsCharge(String.valueOf(pof.getOffsetTime()
					.getTime()));
			payBillInfo
					.setTsBill(String.valueOf(pof.getOffsetTime().getTime()));
			payBillInfo.setBillID(pof.getOffsetID());
			payBillInfo.setChargeType("7");
			payBillInfo.setChargeID(pof.getOffsetID());
			payBillInfo.setChargeUserID(userID);
			payBillInfo.setChargeUserName(userName);
			payBillInfo.setRuleType("0");

			String remark = "  账单时间：" + pof.getFeeDate() + ", 类目："
					+ pof.getFeeTypeName() + ", 金额： " + pof.getAmount()
					+ "元（冲抵）";
			payBillInfo.setRemarkType("1");
			payBillInfo.setRemark(remark);
			payBillInfo.setTypeCode(typeCode);
			/***
			 * "opypte":""//操作类型 add：新增 update：修改 delete：删除
			 */
			payBillInfo.setOpypte("add");
			PayBillInfo payBill = propFeeCommService
					.getPayBillInfo(payBillInfo);
			final Map<String, Object> par = new HashMap<String, Object>();
			List<PayBillInfo> payBillInfos = new ArrayList<PayBillInfo>();
			payBillInfos.add(payBill);
			par.put("sourceList", payBillInfos);
			try {
				Thread thread = new Thread(new Runnable() {

					@Override
					public void run() {
						HttpSvcUtils.doPostInfoSvc(UrlPath.sendInfoToFinance,
								par, null);
					}
				});
				thread.start();

			} catch (Exception e) {
				logger.error(e.getMessage());
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return 1;
	}

	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public void offsetByDetail(String commID, String apartmentID,
			String userID, Map<String, Object> detail, String userName)
			throws AppBizException {

		if (StringUtils.isBlank(commID)) {
			return;
		}

		if (StringUtils.isBlank(apartmentID)) {

			return;
		}

		// 获取房屋账户余额
		PropFeeAccountDto propFeeAccount = propFeeAccountService
				.findAccountByApartID(apartmentID);
		if (propFeeAccount == null) {

			return;
		}

		if (propFeeAccount.getMoney().compareTo(BigDecimal.ZERO) <= 0) {

			return;
		}

		if (detail == null) {

			return;

		}
		;
		BigDecimal money = propFeeAccount.getMoney();
		// 获取该用户的缴费细项信息

		// List<Map<String, Object>> details = feeDetailService
		// .getFeeDetailsForOffset(apartmentID, commID);
		// if (details == null || details.size() == 0) {
		//
		// return;
		//
		// }
		//

		// 遍历进行代扣操作
		BigDecimal amount = null;
		List<String> feeDetailIDs = new ArrayList<String>();

		String minDate = null;
		String mon = null;

		// for (Map<String, Object> map : details) {
		//
		try {
			Thread.sleep(10);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		amount = new BigDecimal(detail.get("amount").toString());
		mon = detail.get("fee_date").toString();

		if (money.compareTo(amount) >= 0) {
			String offsetID = IdUtil.getuuId();
			// 扣钱
			AmountHandleDto a = new AmountHandleDto();
			a.setAccountID(propFeeAccount.getAccountID());
			a.setMoney(amount);
			a.setRemark(detail.get("fee_type_name").toString());
			a.setItem(detail.get("fee_type_name").toString());
			a.setApartmentID(propFeeAccount.getApartmentID());
			a.setLinkID(offsetID);
			a.setTotalMoney(money);

			Map<String, Object> m = new HashMap<String, Object>();
			m.put("feeDate", mon);
			m.put("feeDetailID", detail.get("fee_detail_id").toString());
			a.setLogContent(JSONObject.fromObject(m).toString());
			a.setOperation("2");
			a.setLogType(8);
			a.setStatementType("7");
			propFeeAccountService.handleAccount(a);
			// 生成冲抵明细
			PropFeeOffsetInfoDto pof = new PropFeeOffsetInfoDto();
			pof.setAmount(amount);
			pof.setOffsetMoney(amount);
			pof.setFeeDate(detail.get("fee_date").toString());
			pof.setFeeDetailID(detail.get("fee_detail_id").toString());
			pof.setFeeTypeID(detail.get("fee_type_id").toString());
			pof.setCommID(commID);
			pof.setApartmentID(apartmentID);
			pof.setOffsetTime(new Date());
			pof.setOffsetType("1");
			propFeeOffsetInfoService.addPropFeeOffsetInfo(pof);
			pof.setFeeTypeName(detail.get("fee_type_name").toString());
			pof.setFeeDate(mon);
			// 设置细项为已支付
			feeDetailIDs.add(detail.get("fee_detail_id").toString());

			money = money.subtract(amount);

			try {
				// 同步数据到财务中心
				// sendInfoToFinal(pof, commID, apartmentID,
				// detail.get("fnumber")
				// .toString(), userID, userName);
			} catch (Exception e) {
				// TODO: handle exception
			}
		} else {
			minDate = mon;

		}
		//
		// }
		if (feeDetailIDs != null && feeDetailIDs.size() > 0) {
			feeDetailService.setFeeDetailsPay(apartmentID, feeDetailIDs,
					new Date());
		}

	}

	/***
	 * 自主选择缴费细想代扣
	 */
	@Override
	@Transactional(rollbackFor = { AppBizException.class, Exception.class,
			RuntimeException.class })
	public  synchronized void offsetByDetail(String commID, String apartmentID,
			String userID, List<String> detailIDs, String userName,
			String linkID, BigDecimal payMoney) throws AppBizException {

		if (StringUtils.isBlank(commID)) {
			return;
		}

		if (StringUtils.isBlank(apartmentID)) {
			return;
		}
		if (detailIDs == null || detailIDs.size() <= 0) {
			return;
		}
		// 获取房屋账户余额
		PropFeeAccountDto propFeeAccount = propFeeAccountService
				.findAccountByApartID(apartmentID);
		if (propFeeAccount == null) {
			return;
		}

		BigDecimal money = propFeeAccount.getMoney();
		/***
		 * 房屋账户是否负数
		 */
		BigDecimal souremoney = propFeeAccount.getMoney();
		// 获取该用户的缴费细项信息
		Map<String, Object> propFeeDetail = new HashMap<String, Object>();
		propFeeDetail.put("feeDetailIDs", detailIDs);
		propFeeDetail.put("status", "0");
		List<Map<String, Object>> details = feeDetailService
				.findropFeeDetailByMap(propFeeDetail);
		if (details == null || details.size() == 0) {
			return;
		}
		BigDecimal totlalMoney = new BigDecimal("0");
		for (Map<String, Object> map : details) {
			totlalMoney = totlalMoney.add(new BigDecimal(map.get("amount")
					.toString()));
		}

		if (totlalMoney.compareTo(payMoney) != 0) {
			throw new AppBizException(2, "亲，金额不符合");

		}
		// 遍历进行代扣操作
		BigDecimal amount = null;
		List<String> feeDetailIDs = new ArrayList<String>();
		String mon = null;
		for (Map<String, Object> map : details) {
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
			}
			amount = new BigDecimal(map.get("amount").toString());

			String offsetID = IdUtil.getuuId();
			// 扣钱
			AmountHandleDto a = new AmountHandleDto();
			a.setAccountID(propFeeAccount.getAccountID());
			a.setMoney(amount);
			a.setRemark(map.get("fee_type_name").toString());
			a.setItem(map.get("fee_type_name").toString());
			a.setApartmentID(propFeeAccount.getApartmentID());
			a.setLinkID(offsetID);
			a.setTotalMoney(money);
			Map<String, Object> m = new HashMap<String, Object>();
			m.put("feeDate", map.get("fee_date"));
			m.put("feeDetailID", map.get("fee_detail_id").toString());
			a.setLogContent(JSONObject.fromObject(m).toString());
			a.setOperation("2");
			a.setLogType(PropFeeAmountLogDto.OFFSET);
			a.setStatementType("7");
			// propFeeAccountService.handleAccount(a);
			propFeeAccountService.handleAccountLog(a, propFeeAccount);
			// 生成冲抵明细
			PropFeeOffsetInfoDto pof = new PropFeeOffsetInfoDto();
			pof.setAmount(amount);
			pof.setOffsetMoney(amount);
			pof.setFeeDate(map.get("fee_date").toString());
			pof.setFeeDetailID(map.get("fee_detail_id").toString());
			pof.setFeeTypeID(map.get("fee_type_id").toString());
			pof.setCommID(commID);
			pof.setApartmentID(apartmentID);
			pof.setOffsetTime(new Date());
			pof.setOffsetType("3");
			pof.setOrderID(linkID);
			pof.setAccountID(propFeeAccount.getAccountID());
			propFeeOffsetInfoService.addPropFeeOffsetInfo(pof);
			pof.setFeeTypeName(map.get("fee_type_name").toString());
			pof.setFeeDate(mon);
			// 设置细项为已支付
			feeDetailIDs.add(map.get("fee_detail_id").toString());
			money = money.subtract(amount);
			propFeeAccount.setMoney(money);
			try {
				// // 同步数据到财务中心
				// sendInfoToFinal(pof, commID, apartmentID, map
				// .get("fnumber").toString(), userID, userName);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}

		if (feeDetailIDs != null && feeDetailIDs.size() > 0) {
			Map<String, Object> param = new HashMap<String, Object>();
			param.put("apartmentID", apartmentID);
			param.put("accountID", propFeeAccount.getAccountID());
			param.put("money", payMoney);

			/***
			 * 房屋账
			 */
			// if (souremoney.compareTo(new BigDecimal("0")) > 0) {
			// int n = this.getSqlSession().update(
			// "PropFeeAccountMapper.subAccount", param);
			// } else {
			int n = this.getSqlSession().update(
					"PropFeeAccountMapper.subAccountInfo", param);
			// }

			feeDetailService.setFeeDetailsPay(apartmentID, feeDetailIDs,
					new Date());
		}

	}
}
